<template>
  <div
    v-if="attachments && attachments.length"
    :style="{ display: 'grid', gridTemplateColumns: gridColumn, gap: gridGap, width: '100%', overflow: 'hidden' }"
    class="attachments"
  >
    <div class="attachments-item" v-for="(item, index) in attachments" :key="index">
      <div class="attachments-item-wrap">
        <a-image
          v-if="getFileType(item) === 'image'"
          :src="item[fields.url]"
          :width="'100%'"
          :height="size + 'px'"
          style="width: 100%; height: 100%; object-fit: cover"
        />
        <CustomerServiceOutlined
          v-else-if="getFileType(item) === 'audio'"
          :style="{ fontSize: size + 'px' }"
          @click="onPreview(item)"
        />
        <VideoCameraOutlined
          v-else-if="getFileType(item) === 'video'"
          :style="{ fontSize: size + 'px' }"
          @click="onPreview(item)"
        />
        <FileTextOutlined
          v-else-if="getFileType(item) === 'doc'"
          :style="{ fontSize: size + 'px' }"
          @click="openNewPage(item)"
        />
        <FileOutlined v-else :style="{ fontSize: size + 'px' }" @click="openNewPage(item)" />
      </div>
      <div v-if="item[fields.name]" :title="item[fields.name]" class="attachments-item-name">
        {{ item[fields.name] }}
      </div>
    </div>
  </div>
  <div v-else><slot name="empty">-</slot></div>
</template>

<script>
import { CustomerServiceOutlined, VideoCameraOutlined, FileTextOutlined, FileOutlined } from '@ant-design/icons-vue';
import { Image } from 'ant-design-vue';
import { h } from 'vue';
import { getFileType, getUrlName } from '@gis/lib/components/Uploader/upload-utils.js';
import { dialog } from '@gis/lib/components/antd-dialog/index.js';

export default {
  name: 'attachment-list',
  components: {
    CustomerServiceOutlined,
    VideoCameraOutlined,
    FileTextOutlined,
    FileOutlined,
    Image,
  },
  props: {
    data: { type: [String, Array], default: undefined },
    dataList: { type: [String, Array], default: undefined },
    nameList: { type: [String, Array], default: undefined },
    replaceFields: { type: Object, default: undefined },
    gutter: { type: [Number, String], default: 12 },
    colSpan: { type: Number, default: 4 },
    size: { type: Number, default: 60 },
  },
  computed: {
    gridColumn() {
      let column = Math.floor(24 / (parseInt(this.colSpan) || 6));
      return Array.apply(null, { length: column })
        .map(() => '1fr')
        .join(' ');
    },
    gridGap() {
      return Number.isFinite(this.gutter) ? this.gutter + 'px' : this.gutter || '12px';
    },
    fields() {
      const opt = { type: 'attachment_type', name: 'attachment_name', url: 'attachment_url' };
      return Object.assign({}, opt, this.replaceFields);
    },
    attachments() {
      let data = this.getListFromStr(this.dataList || this.data);
      let names = this.getListFromStr(this.nameList);
      return data.reduce((res, item, index) => {
        if (!item) return res;
        if (typeof item === 'string') {
          item = { [this.fields.url]: item, [this.fields.name]: names[index] || getUrlName(item) };
        }
        return res.concat([item]);
      }, []);
    },
  },
  methods: {
    onPreview(item) {
      let renderer = {
        audio: (item) => {
          return h('audio', {
            src: item[this.fields.url],
            style: { width: '100%', height: '100%', objectFit: 'cover' },
          });
        },
        video: (item) => h('video', { src: item[this.fields.url], style: { width: '100%' } }),
      };
      let render = renderer[this.getFileType(item)];
      dialog({
        content: h(
          'div',
          {
            style: { display: 'flex', justifyContent: 'center', alignItems: 'center', width: '600px', height: '400px' },
          },
          typeof render === 'function' && render(item)
        ),
        dialogProps: {
          title: item[this.fields.name] || '预览',
          okButtonProps: {
            href: item[this.fields.url],
            download: item[this.fields.name],
            target: '_blank',
          },
          width: '600px',
          okText: '下载',
          cancelText: '关闭',
        },
      });
    },
    getListFromStr(str) {
      if (typeof str === 'string') str = str.split(',');
      if (Array.isArray(str)) return str;
      return [];
    },
    getFileType(item) {
      return getFileType({ name: item[this.fields.url] });
    },
    openNewPage(item) {
      window.open(item[this.fields.url], '_blank');
    },
  },
};
</script>

<style lang="less">
.attachments {
  .attachments-item {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    width: 100%;
    text-align: center;
    overflow: hidden;
    color: #a0a0a0;
    .attachments-item-wrap {
      box-sizing: border-box;
      width: 100%;
      padding: 6px;
      border: 1px solid var(--border-color-1, #d9d9d9);
      border-radius: 4px;
    }
    .attachments-item-name {
      width: 100%;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      text-align: center;
      font-size: 12px;
      font-weight: normal;
      letter-spacing: 0;
    }
  }
}
</style>
